/**
 * onChange事件会让InputRender在父组件上重新渲染导致失去焦点直接通过{InputRender()}这样的方式渲染
 * {InputRender()}和<InputRender />的区别在与<InputRender />每次更新会被卸载掉然后重新渲染针对onChange事件
 * <InputRender />.type() === InputRender()
 * 这个hooks不能用在循环中
 */

 import React, { useState, useEffect, useRef } from 'react';

 import { Input, InputProps } from 'antd';

 type inputType =
   | {
       /** 防抖 */ type: 'debounce';
       defaultValue?: InputProps['defaultValue'];
       /** 防抖间隔 */ debounceTime?: number;
     }
   | {
       /** 节流 */ type: 'throttle';
       defaultValue?: InputProps['defaultValue'];
       /** 节流间隔 */ throttleTime?: number;
     };

 export default function(
   props?: inputType,
 ): {
   value: any;
   DOM: (e: InputProps) => JSX.Element;
 } {
   const { defaultValue = '', type = 'normal', debounceTime = 300, throttleTime = 300 } =
     props || {};
   const timer = useRef<any>(null);
   const inputRef = useRef<Input>(null);
   const [value, setValue] = useState(defaultValue);
   const isComposition = useRef<boolean>(false);
   const DOM = (e: InputProps): JSX.Element => {
     // onChange事件调试{InputRender()}和<InputRender />渲染情况
     // useEffect(() => {
     //   console.log(12)
     //   return () => {
     //     console.log(453534534)
     //   }
     // }, [])
     return (
       <Input
         {...e}
         ref={inputRef}
         defaultValue={value}
         onBlur={e => setValue(e.target.value)}
         onCompositionStart={() => { // 拼音输入
           isComposition.current = true;
           if (timer.current && type === 'debounce') {
             clearTimeout(timer.current);
             timer.current = null;
           }
         }}
         onCompositionEnd={e => { // 拼音输入
           isComposition.current = false;
           let currentValue = inputRef.current?.input?.value || '';
           if (type === 'debounce') {
             timer.current = setTimeout(() => {
               setValue(currentValue);
             }, debounceTime);
           } else if (type === 'throttle') {
             if (!timer.current)
               timer.current = setTimeout(() => {
                 setValue(inputRef.current?.input?.value || value);
                 clearTimeout(timer.current);
                 timer.current = null;
               }, throttleTime);
           } else {
             setValue(currentValue);
           }
         }}
         onChange={e => {
           if (isComposition.current) return;
           let currentValue = e.target.value;
           console.log(currentValue)
           if (type === 'debounce') {
             if (timer.current) {
               clearTimeout(timer.current);
               timer.current = null;
             }
             timer.current = setTimeout(() => {
               setValue(currentValue);
             }, debounceTime);
           } else if (type === 'throttle') {
             if (!timer.current)
               timer.current = setTimeout(() => {
                 setValue(inputRef.current?.input?.value || value);
                 clearTimeout(timer.current);
                 timer.current = null;
               }, throttleTime);
           } else {
             setValue(currentValue);
           }
         }}
       />
     );
   };
   return {
     value,
     DOM,
   };
 }
